package pay.portal;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import pay.base.BaseCtrl;
import pay.base.ResponseBase;
import pay.common.CardStatusCode;
import pay.common.ConstantFYJZH;
import pay.common.HqlFilter;
import pay.common.ResultCode;
import pay.entity.Payment;
import pay.entity.SysUser;
import pay.portal.web.message.ChangeCardReq;
import pay.portal.web.message.UserChangeCardReqData;
import pay.service.IPayment;
import pay.service.sys.ISysUser;
import pay.utils.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 实现换卡相关的功能
 */
@Controller
@RequestMapping(value = BaseCtrl.App)
public class ChangeCardCtrl extends BaseCtrl {

    private Logger logger = LoggerFactory.getLogger(ChangeCardCtrl.class);


    @Value("${fy.mchntCd}")
    private String mchnt_cd;

    @Autowired
    private ISysUser userService;

    @Value("${fy.withdrawLogFilePath}")
    private String logFilePath;

    /**
     * 商户代码，从配置文件中读取
     */
    @Value("${server.scheme}")
    private String serverScheme;

    @Value("${fy.goldAccount.pathBaseUrl}")
    private String pathBaseUrl; // 测试环境为/jzh 生产无。

    /**
     * 金账户baseURl，从配置文件中读取
     */
    @Value("${fy.goldAccount.baseUrl}")
    private String jzhBaseUrl;


    @Autowired
    private IPayment paymentService;

    /**
     * 换卡
     *
     * @param req
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/changeCard", method = RequestMethod.POST)
    public ResponseBase<Boolean> changeCard(@RequestBody ChangeCardReq req) {
        ResponseBase<Boolean> responseBase = new ResponseBase<>();

        if (req == null ||req.getOldPaymentId() == null|| StringHelper.isEmpty(req.getUserId()) || StringHelper.isEmpty(req.getBankCd())
                || StringHelper.isEmpty(req.getCityId()) || StringHelper.isEmpty(req.getCardNo())
                || StringHelper.isEmpty(req.getPicId01()) || StringHelper.isEmpty(req.getPicId02()) || StringHelper.isEmpty(req.getMchnt_txn_ssn())) {
            responseBase.setResultCode(ResultCode.PARAM_ERROR.getCode());
            responseBase.setMsg("必传参数为空，此次换卡请求失败");
            return responseBase;
        }

        String picId01 = req.getPicId01();
        String picId02 = req.getPicId02();

        if (!PicUtil.checkFileExist(picId01) || !PicUtil.checkFileExist(picId02)) {
            logger.error("图片未成功上传，此次换卡请求失败");
            responseBase.setResultCode(ResultCode.PARAM_ERROR.getCode());
            responseBase.setMsg("图片未成功上传，此次换卡请求失败");
            return responseBase;
        }

        if( picId01.equalsIgnoreCase(picId02)) {
            logger.error("上传了2张同样的图片，此次换卡请求失败");
            responseBase.setResultCode(ResultCode.PARAM_ERROR.getCode());
            responseBase.setMsg("上传了2张同样的图片，此次换卡请求失败");
            return responseBase;
        }

        Payment pay = paymentService.findById(req.getOldPaymentId());
        if(pay == null){
            logger.info("旧的支付方式不存在，此次换卡请求失败");
            responseBase.setResultCode(ResultCode.FAILED.getCode());
            responseBase.setMsg("旧的支付方式不存在，此次换卡请求失败");
            return responseBase;
        }

        if(pay.getCardStatus() != CardStatusCode.PAYMENT_DISPLAY_SHOW ){
            logger.info("旧卡的状态错误，此次换卡请求失败");
            responseBase.setResultCode(ResultCode.FAILED.getCode());
            responseBase.setMsg("旧卡的状态错误，此次换卡请求失败");
            return responseBase;
        }


        UserChangeCardReqData userChangeCardReqData = getUserChangeCardReqData(req);

        String resultStr;
        try {
            logger.info("ChangeCard Request = {}", userChangeCardReqData.toString());
            resultStr = FYApiUtil.userChangeCard(userChangeCardReqData);
            logger.info("ChangeCard Result ={}", resultStr);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("send post to FY for change card error e={}", e);
            responseBase.setResultCode(ResultCode.FAILED.getCode());
            responseBase.setMsg("换卡异常，，此次换卡请求失败");
            return responseBase;
        }

        String resp_code = XmlUtils.getVal(resultStr, "resp_code");
        String resp_desc = XmlUtils.getVal(resultStr, "resp_desc");
        String mchnt_txn_ssn = XmlUtils.getVal(resultStr, "mchnt_txn_ssn");

        logger.info("resultStr = " + resultStr);
        logger.info("resp_code = " + resp_code);

        addIntoLogFile(userChangeCardReqData, resp_code, resp_desc);

        if (resp_code.equals("0000")) {
            updateCardStatus(req.getOldPaymentId(), true, mchnt_txn_ssn);
            logger.info("富有换卡成功 UserChangeCardReqData={}", userChangeCardReqData.toString());
            responseBase.setResult(true);
            responseBase.setResultCode(ResultCode.SUCC.getCode());
            responseBase.setMsg("此次换卡成功");
        } else {
            logger.info("富有换卡失败 UserChangeCardReqData={}", userChangeCardReqData.toString());
            responseBase.setResult(false);
            responseBase.setResultCode(ResultCode.SUCC.getCode());
            responseBase.setMsg(resp_desc);
        }
        return responseBase;
    }

    private UserChangeCardReqData getUserChangeCardReqData(ChangeCardReq req) {
        String userIdStr = req.getUserId();
        Long userIdLong = Long.valueOf(userIdStr);
        // 流水号
        String mchnt_txn_ssn = req.getMchnt_txn_ssn();

        SysUser user = userService.findById(userIdLong);
        String login_id = user.getName();
        String city_id = req.getCityId();
        String bank_cd = req.getBankCd();
        String card_no = req.getCardNo();

        String picId01 = req.getPicId01();
        String picId02 = req.getPicId02();
        File file1 = PicUtil.getPicById(picId01);
        File file2 = PicUtil.getPicById(picId02);

        UserChangeCardReqData userChangeCardReqData = new UserChangeCardReqData();
        userChangeCardReqData.setBank_cd(bank_cd);
        userChangeCardReqData.setCard_no(card_no);
        userChangeCardReqData.setCity_id(city_id);
        userChangeCardReqData.setLogin_id(login_id);
        userChangeCardReqData.setMchnt_cd(mchnt_cd);
        userChangeCardReqData.setMchnt_txn_ssn(mchnt_txn_ssn);
        userChangeCardReqData.setFile1(file1);
        userChangeCardReqData.setFile2(file2);

        String pathUrl = "https://" + jzhBaseUrl + pathBaseUrl + "/userChangeCard.action";
        logger.info("pathUrl ={}", pathUrl);
        userChangeCardReqData.setPathUrl(pathUrl);
        return userChangeCardReqData;
    }


    /**
     * 将请求结果写入日志文件
     * @param userChangeCardReqData
     * @param resp_code
     * @param resp_desc
     */
    private void addIntoLogFile(UserChangeCardReqData userChangeCardReqData, String resp_code, String resp_desc) {
        //将预授权记录写入日志文件

        ExecutorService executor = Executors.newFixedThreadPool(1);
        Runnable task = () -> {
            try {
                String logRecord = DateUtil.transferLongToDate(
                        "yyyy-MM-dd HH:mm:ss", System.currentTimeMillis())
                        + "-- 富友换卡接口入参: mchnt_txn_ssn = "
                        + userChangeCardReqData.getMchnt_txn_ssn()
                        + ", bank_cd = "
                        + userChangeCardReqData.getBank_cd()
                        + ", card_no = "
                        + userChangeCardReqData.getCard_no()
                        + ", city_id = "
                        + userChangeCardReqData.getCity_id()
                        + ", phone_no = "
                        + userChangeCardReqData.getLogin_id()
                        + ", resp_code = " + resp_code
                        + ", resp_desc = " + resp_desc
                        + "\r\n";
                logger.info("富友划拨接口入参 = " + logRecord);
                writeFile(logRecord);

            } catch (Exception e) {
                logger.error("写绑卡文本文件失败！", e);
            }
        };
        executor.execute(task);
        executor.shutdown();
    }

    public void writeFile(String record) {
        try {
            Long cts = System.currentTimeMillis();
            String pathName = "fyChangeCardLogRecords-"
                    + DateUtil.transferLongToDate("yyyyMM", cts) + ".txt";

            Path filePath = Paths.get(logFilePath + pathName);

            if (!Files.exists(filePath)) {
                Files.createFile(filePath);
            }

            Files.write(filePath, record.getBytes("UTF-8"),
                    StandardOpenOption.APPEND);
        } catch (IOException e) {
            logger.error("首次写文件失败！", e);
        }
    }


    /**
     * 更改旧卡的状态为换卡过程中
     * @param oldPaymentId
     * @param status
     */
    public void updateCardStatus(Long oldPaymentId, Boolean status, String mchnt_txn_ssn){
        if(status){
            logger.info("chang card submit success, and will change card status oldPaymentId = {}", oldPaymentId);
            ExecutorService executor = Executors.newFixedThreadPool(1);
            Runnable task = () -> {
                Payment pay = paymentService.findById(oldPaymentId);
                pay.setCardStatus(CardStatusCode.FY_CHANGE_CARDING);
                pay.setMchnt_txn_ssn(mchnt_txn_ssn);
                paymentService.update(pay);
            };
            executor.execute(task);
            executor.shutdown();
        }
    }


}
